﻿using System;
using System.IO;
using System.Linq;
namespace Homework16
{
    /// <summary>
    /// 生成10000行数据，包含序号、人名、年龄、生日、身高、性别
    /// </summary>
    internal class Program
    {
        static void Main(string[] args)
        {
            Random rand = new Random();
            //random gender
            string[] genders = { "Male", "Female" };
            //filepath
            string filePath = @"D:\samples.txt";

            using (StreamWriter sw = new StreamWriter(filePath))
            {
                //output 10000 lines
                for (int i = 1; i <= 10000; i++)
                {
                    // random name
                    string name = RandomName(rand, 3);

                    // age,正态分布
                    int age = NormalDistributedAge(rand, 45, 10, 0, 100);

                    // compute birthday according to age
                    DateTime birthDate = BirthDate(age);

                    // random height
                    double height = rand.NextDouble() * (200 - 150) + 150;

                    // random gender
                    string gender = genders[rand.Next(genders.Length)];

                    // output
                    sw.WriteLine($"{i},{name},{age},{birthDate:yyyy-MM-dd},{height:F2},{gender}");
                }
            }

            Console.WriteLine("数据已成功保存到文件：" + filePath);
        }

        static string RandomName(Random rand, int length)
        {
            const string chars = "abcdefghijklmnopqrstuvwxyz";
            return char.ToUpper(chars[rand.Next(chars.Length)]) + new string(Enumerable.Repeat(chars, length - 1).Select(s => s[rand.Next(s.Length)]).ToArray());
        }

        static int NormalDistributedAge(Random rand, double mean, double stdDev, int minAge, int maxAge)
        {
            // uniform(0,1] random doubles
            double u1 = 1.0 - rand.NextDouble(); 
            double u2 = 1.0 - rand.NextDouble();
            // convert to standard normal
            double z0 = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Cos(2.0 * Math.PI * u2);
            // translate to mean and standard deviation
            double age = mean + z0 * stdDev; 

            // Ensure the age is within the specified range
            return Math.Max(minAge, Math.Min(maxAge, (int)age));
        }

        static DateTime BirthDate(int age)
        {
            Random rand = new Random();
            DateTime now = DateTime.Today;
            int year = now.Year - age;
            // random month
            int month = rand.Next(1, 13);
            // random day
            int day = rand.Next(1, DateTime.DaysInMonth(year, month) + 1); 
            return new DateTime(year, month, day);
        }
    }
}
            
    

